package br.unifor.cct.mia.ga.coevolutionary;

import br.unifor.cct.mia.coevolution.CoevolutionaryDomain;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.evolutionary.Individual;
import br.unifor.cct.mia.evolutionary.SpeciesConstants;
import br.unifor.cct.mia.ga.Ga;
import br.unifor.cct.mia.ga.GaISFixedSize;

public class CoevGaISFixedSize extends Ga {
	
	private static String[] configuracoes = {
		"br.unifor.cct.mia.xover.BasicXOver",
		"br.unifor.cct.mia.select.TournamentMaximize",
		"br.unifor.cct.mia.coevolution.evaluate.CoevolutionaryEvaluation",
		"br.unifor.cct.mia.mutation.MutationOriginal",
		"br.unifor.cct.mia.initialize.FixedSizeRandomInitialize"
	};
	private Structure structure;
	private Database dbOriginal;
	private CoevolutionaryDomain domain;	
	private Integer specieType = new Integer(SpeciesConstants.INSTANCE_SELECTION_FS);
	
	public CoevGaISFixedSize(Database dbOriginal, Structure structure, CoevolutionaryDomain domain, String[] options) {
		super(GaISFixedSize.NVARS, configuracoes, options);
		System.out.println("Iniciando populacao de Instance Selection FS ("+GaISFixedSize.NVARS+")");
		this.dbOriginal = dbOriginal;
    	this.structure = structure;
    	this.domain = domain;
	}
	
	protected void elitist() {
		if (population[indexBestWorst[0]].getFitness() > population[configurations.getPopsize()].getFitness()) {
			population[configurations.getPopsize()] = (Individual)population[indexBestWorst[0]].clone();
		} else {
			population[indexBestWorst[1]] = (Individual)population[configurations.getPopsize()].clone();
			population[indexBestWorst[0]] = (Individual)population[configurations.getPopsize()].clone();
		}
		population[indexBestWorst[0]] = (Individual)population[configurations.getPopsize()].clone();
		
		domain.reloadGraphic(generation,this);
	}
	
	public Object[] getObjectsMutate() {
		Object[] o = new Object[1];
		o[0] = this;		
		return o;
	}
	
	public Object[] getObjectsSelect() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}
	
	public Object[] getObjectsEvaluate() {
		Object[] o = new Object[5];
		o[0] = domain;
		o[1] = specieType;
		o[2] = structure;
		o[3] = dbOriginal;
		o[4] = this;
		return o;
	}
	
	public Object[] getObjectsCrossover() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}
	
	public Object[] getObjectsInitialize() {
		Object[] o = new Object[2];		
		o[0] = new Integer(dbOriginal.size());
		o[1] = this;
		return o;
	}        
	
	public Integer getSpecieType() {
		return specieType;
	}

	public void setSpecieType(Integer specieType) {
		this.specieType = specieType;
	}
}
